<!-- 路由 -->
// 导入组件
import Vue from "vue";
import Router from "vue-router";
// 登录
import login from "@/views/login";
// 首页
import index from "@/views/index";
/**
 * 基础菜单
 */
// 虚拟人列表
import creact from "@/views/creact/creact";
// 虚拟人交互模拟
import exchange from "@/views/exchange/exchange";
// 虚拟人交互分析
import InteractionAnalysis from "@/views/InteractionAnalysis/InteractionAnalysis";
// 交互记录
import InteractionRecords from "@/views/InteractionRecords/InteractionRecords";
// 交互详情
import InteractionRecordsDetails from "@/views/InteractionRecordsDetails/InteractionRecordsDetails";
//学术库内容审核
import Auditing from "@/views/Auditing/Auditing";
// 学术库问答训练
import train from "@/views/train/train";
// 用户管理
import user from "@/views/system/user";
// 角色管理
import Role from "@/views/system/Role";
// 日志管理
import log from "@/views/system/log";
//  首页概览
import homePage from "@/views/charts/homePage";
// 启用路由
Vue.use(Router);
// 导出路由
export default new Router({
  routes: [
    {
      path: "/",
      name: "",
      component: login,
      hidden: true,
      meta: {
        requireAuth: false,
      },
    },
    {
      path: "/login",
      name: "登录",
      component: login,
      hidden: true,
      meta: {
        requireAuth: false,
      },
    },
    {
      path: "/index",
      name: "首页",
      component: index,
      iconCls: "el-icon-tickets",
      children: [
        {
          path: "/homePage",
          name: "首页",
          component: homePage,
          meta: {
            requireAuth: true,
          },
        },
        {
          path: "/creact/creact",
          name: "虚拟人创建与定制",
          component: creact,
          meta: {
            requireAuth: true,
          },
        },
        {
          path: "/exchange/exchange",
          name: "虚拟人交互模拟",
          component:exchange,
          meta: {
            requireAuth: true,
          },
        },
        {
            path: "/InteractionRecords/InteractionRecords",
            name: "交互记录",
            component: InteractionRecords,
            meta: {
              requireAuth: true,
            },
        },
        {
            path: "/InteractionRecordsDetails/InteractionRecordsDetails",
            name: "交互详情",
            component: InteractionRecordsDetails,
            meta: {
              requireAuth: true,
            },
        },
        {
          path: "/InteractionAnalysis/InteractionAnalysis",
          name: "虚拟人交互分析",
          component: InteractionAnalysis,
          meta: {
            requireAuth: true,
          },
      },
        {
            path: "/Auditing/Auditing",
            name: "学术库内容审核",
            component: Auditing,
            meta: {
              requireAuth: true,
            },
        },
        {
            path: "/train/train",
            name: "保鲜效果监测",
            component: train,
            meta: {
              requireAuth: true,
            },
        },
        {
          path: "/system/user",
          name: "用户管理",
          component: user,
          meta: {
            requireAuth: true,
          },
        },
        {
          path: "/system/Role",
          name: "角色管理",
          component: Role,
          meta: {
            requireAuth: true,
          },
        },
        {
          path: "/system/log",
          name: "日志管理",
          component: log,
          meta: {
            requireAuth: true,
          },
        },
      ],
    },
  ],
});
<!-- 登录 -->
<template>
  <div class="login-wrap">
    <el-form label-position="left" :model="loginUserForm" :loginrules="loginrules" ref="loginUserForm" label-width="0px" class="demo-loginUserForm login-container">
      <h3 class="title">肇远数字虚拟人后台记录管理系统</h3>
      <el-form-item prop="username">
        <el-input type="text" v-model="loginUserForm.username" auto-complete="off" placeholder="账号"></el-input>
      </el-form-item>
      <el-form-item prop="password">
        <el-input type="password" v-model="loginUserForm.password" auto-complete="off" placeholder="密码"></el-input>
      </el-form-item>
      <el-row>
        <el-col :span="12">
          <el-form-item prop="code">
            <el-input type="text" v-model="loginUserForm.code" auto-complete="off" placeholder="图形验证码" @keyup.enter.native="submitLogin('loginUserForm')"></el-input>
          </el-form-item>
        </el-col> 
        <el-col :span="12" class="code-box">
          <img :src="loginUserForm.codeimg" alt="" class="codeimg" @click="getcode()">
        </el-col>
      </el-row>
      <el-checkbox class="remember" v-model="rememberpwd">记住密码</el-checkbox>
      <el-form-item style="width:100%;margin:0 auto">
        <el-button type="primary" style="width:40%; margin-right: 30px;" @click="submitLogin('loginUserForm')" :loading="logining">登录</el-button>
        <el-button style="width:40%;" @click="resetLogin">重置</el-button> 
        <el-link type="text" @click="modifypw">忘记密码？</el-link>   
      </el-form-item>
    </el-form>
    <el-dialog :visible.sync="passwordVisible" title="重置密码">
      <el-form
        :model="modifypwLogin"
        :loginrules="modifypwloginrules"
        ref="modifypwLogin"
        label-width="120px"
      >
        <el-form-item label="新密码" prop="newPassword">
          <el-input
            type="password"
            v-model="modifypwLogin.newPassword"
            placeholder="请输入新密码"
          ></el-input>
        </el-form-item>
        <el-form-item label="确认密码" prop="confirmPassword">
          <el-input
            type="password"
            v-model="modifypwLogin.confirmPassword"
            placeholder="请再次输入新密码"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handlemodifypwSubmit"
            >提交</el-button
          >
          <el-button @click="modifypwVisible = false">取消</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>
<script type="text/ecmascript-6">
import { login } from '../api/userMG'
import { setCookie, getCookie, delCookie } from '../utils/util'
import md5 from 'js-md5'
export default {
  name: 'userlogin',
  data() {
    return {
      //定义loading默认为false
      logining: false,
      // 记住密码
      rememberpwd: false,
      loginUserForm: {
        //username和password默认为空
        username: '',
        password: '',
        code: '',
        randomStr: '',
        codeimg: ''
      },
      //loginrules前端验证
      loginrules: {
        username: [{ required: true, message: '请输入用户账号', trigger: 'blur' }],
        password: [{ required: true, message: '请输入用户密码', trigger: 'blur' }],
        code: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
      },
      passwordVisible: false,
      passwordForm: {
        newPassword: "",
        confirmPassword: "",
      },
      modifypwloginrules: {
        newPassword: [
          { 
            required: true,
             message: "请输入新密码",
              trigger: "blur" 
          },
          {
            min: 6,
            max: 16,
            message: "长度在 6 到 20个字符",
            trigger: "blur",
          },
        ],
        confirmPassword: [
          { required: true, 
            message: "请再次输入新密码",
             trigger: "blur"
          },
          { 
            validator: this.validateConfirmPassword, 
            trigger: "blur" 
          },
        ],
      },
      modifypwLogin: {
        newPassword: "",
        confirmPassword: "",
      },
    }
  },
  // 创建完毕状态(里面是操作)
  created() {
    this.$message({
      message: '账号密码和验证码不能为空',
      type: 'success'
    })
    // 获取图形验证码
    this.getcode()
    // 获取存在本地的用户名密码
    this.getpw()
  },
  // 里面的函数只有调用才会执行
  methods: {
    // 获取用户名密码
    getpw() {
      if (getCookie('login') != '' && getCookie('pwd') != '') {
        this.loginUserForm.username = getCookie('login')
        this.loginUserForm.password = getCookie('pwd')
        this.rememberpwd = true
      }
    },
    //获取info列表
    submitLogin(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          this.logining = true
          // 测试通道，不为空直接登录
          setTimeout(() => {
            this.logining = false
            this.$store.commit('login', 'true')
            this.$router.push({ path: '/surgical/surgical' })
          }, 1000)
          // 正式环境
          login(this.loginUserForm).then(res => {
            if (res.success) {
              if (this.rememberpwd) {
                //保存帐号到cookie，有效期7天
                setCookie('login', this.loginUserForm.username, 7)
                //保存密码到cookie，有效期7天
                setCookie('pwd', this.loginUserForm.password, 7)
              } else {
                delCookie('logi')
                delCookie('pwd')
              }
              //如果请求成功就让他2秒跳转路由
              setTimeout(() => {
                this.logining = false
                // 缓存token
                localStorage.setItem('logintoken', res.data.token)
                // 缓存用户个人信息
                localStorage.setItem('userdata', JSON.stringify(res.data))
                this.$store.commit('login', 'true')
                this.$router.push({ path: '/surgical/surgical' })
              }, 1000)
            } else {
              this.$message.error(res.msg)
              this.logining = false
              return false
            }
          })
        } else {
          // 获取图形验证码
          this.getcode()
          this.$message.error('请输入用户名密码！')
          this.logining = false
          return false
        }
      })
    },
    //密码重置
    modifypw() {
      this.passwordVisible = true;
    },
    // 重置 
    resetLogin() {
      this.$refs.loginloginUserForm.resetFields();
    },
  }
}
</script>
<style scoped>
.login-wrap {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  padding-top: 10%;
  background-image: url('https://img0.baidu.com/it/u=3991709530,2059376514&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281');
  background-repeat: no-repeat;
  background-position: center right;
  background-size: 100%;
}
.login-container {
  border-radius: 10px;
  margin: 0px auto;
  width: 350px;
  padding: 30px 35px 15px 35px;
  background: #fff;
  border: 1px solid #eaeaea;
  text-align: left;
  box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
}
.title {
  margin: 0px auto 40px auto;
  text-align: center;
  color: #505458;
}
.remember {
  margin: 0px 0px 35px 0px;
}
.code-box {
  text-align: right;
}
.codeimg {
  height: 40px;
}
</style>
<!-- 首页 -->
<template>
  <div class="stbox">  
    <el-container>  
      <el-main>  
        <el-row :gutter="20">  
          <el-col :span="24">  
            <h2>虚拟人活动概览</h2>  
            <el-card class="box-card">  
              <div slot="header" class="clearfix">  
                <span>互动次数</span>  
                <el-button style="float: right; padding: 3px 0" type="text">更多</el-button>  
              </div>  
              <div class="interac" v-for="item in interactionData" :key="item.name">  
                <span>{{ item.name }}: {{ item.value }}</span> 
                <el-button class="interac-button" type="success"  @click="interactionClick(item)">查看详情</el-button> 
              </div>  
            </el-card>  
          </el-col>  
          <el-col :span="24">  
            <h2>虚拟人使用统计</h2>  
            <el-card class="box-card">  
              <div slot="header" class="clearfix">  
                <span>使用时长</span>  
                <el-button style="float: right; padding: 3px 0" type="text">更多</el-button>  
              </div>  
              <div>  
                <div ref="timeChart" style="width: 100%; height: 400px;"></div>  
              </div>  
            </el-card>  
          </el-col>  
        </el-row>  
      </el-main>  
    </el-container>  
  </div>
</template>
<script type="text/ecmascript-6">
import Chart from 'echarts'
export default {
  name: "welcome",
  data() {
    return {
      machineNo: '',
      interactionData: [  
        { 
          name: '总互动次数',
           value: 785
           },  
        { 
          name: '今日互动次数', 
          value: 46 
        },  
        { 
          name: '昨日互动次数', 
          value: 39 
        },  
      ],  
      chart: null,  
    }
  },
  // 导入组件
  components: {
    // 点聚合组件
  },
  created() { },
  mounted() {
    this.initTimeChart();  
  },
  // 里面的函数只有调用才会执行
  methods: {
    // 满意度变化
    initTimeChart() {
      let numberOption= {
        title: {  
          text: '虚拟人使用时长统计',  
        },  
        tooltip: {},  
        xAxis: {  
          data: ['2024-04-10', '2024-04-11', '2024-04-12', '2024-04-13', '2024-04-14', '2024-04-15', '2024-04-16'],  
        },  
        yAxis: {},  
        series: [{  
          name: '使用时长（小时）',  
          type: 'bar',  
          data: [3, 2, 3.6, 3, 2, 4, 3],  
        }],  
      }
      this.chart = Chart.init(this.$refs.timeChart)
      this.chart.setOption(numberOption)
    },
    //查看详情
    interactionClick(){
       this.$router.push('/interactionDetails')
    }
  }
};
</script>
<!-- 左边导航菜单 -->
<template>
  <el-menu default-active="2" :collapse="collapsed" collapse-transition  router :default-active="$route.path" unique-opened class="el-menu-vertical-demo" background-color="#334157" text-color="#fff" active-text-color="#ffd04b">
    <div class="logobox">
      肇远数字虚拟人后台记录管理系统
    </div>
    <el-submenu v-for="menu in allmenu" :key="menu.menuid" :index="menu.menuname">
      <template slot="title">
        <span>{{menu.menuname}}</span>
      </template>
      <el-menu-item-group>
        <el-menu-item v-for="chmenu in menu.menus" :index="'/'+chmenu.url" :key="chmenu.menuid">
          <span>{{chmenu.menuname}}</span>
        </el-menu-item>
      </el-menu-item-group>
    </el-submenu>
  </el-menu>
</template>
<script>
import { menu } from '../api/userMG'
export default {
  name: 'leftnav',
  data() {
    return {
      collapsed: false,
      allmenu: []
    }
  },
  created() {
    let res = {
      success: true,
      // 右侧标题
      data: [
      {
          menuid: 1,
          icon: 'li-icon-shangchengxitongtubiaozitihuayuanwenjian91',
          menuname: '首页',
          hasThird: null,
          url: null,
          menus: [
            {
              menuid: 11,
              icon: 'icon-provider-manage',
              menuname: '概览',
              hasThird: 'N',
              url: 'homePage',
              menus: null
            }
          ]
        },
        {
          menuid: 2,
          icon: 'li-icon-xiangmuguanli',
          menuname: '虚拟人管理与配置',
          hasThird: null,
          url: null,
          menus: [
            {
              menuid: 22,
              icon: 'icon-cat-skuQuery',
              menuname: '虚拟人创建与定制', //提供丰富的自定义选项，满足用户个性化需求
              hasThird: 'N',
              url: 'creact/creact',
              menus: null
            },
            {
              menuid: 23,
              icon: 'icon-cat-skuQuery',
              menuname: '虚拟人交互模拟',//模拟用户与虚拟人的交互过程，便于测试与调整。
              hasThird: 'N',
              url: 'exchange/exchange',
              menus: null
            },
          ]
        },
        {
          menuid: 3,
          icon: 'li-icon-dingdanguanli',
          menuname: '交互记录与分析模块',
          hasThird: null,
          url: null,
          menus: [
          {
              menuid: 31,
              icon: 'icon-provider-manage',
              menuname: '虚拟人交互分析',
              hasThird: 'N',
              url: 'InteractionAnalysis/InteractionAnalysis',
              menus: null
            },
            {
              menuid: 32,
              icon: 'icon-order-manage',
              menuname: '交互记录',
              hasThird: 'N',
              url: 'InteractionRecords/InteractionRecords',
              menus: null
            },
          ]
        },
        {
          menuid: 4,
          icon: 'li-icon-dingdanguanli',
          menuname: '学术库管理与维护',
          hasThird: null,
          url: null,
          menus: [
          {
              menuid: 41,
              icon: 'icon-provider-manage',
              menuname: '学术库内容审核',  //学术库 列表
              hasThird: 'N',
              url: 'Auditing/Auditing',
              menus: null
            },
            {
              menuid: 42,
              icon: 'icon-provider-manage',
              menuname: '学术库问答训练', 
              hasThird: 'N',
              url: 'train/train',
              menus: null
            },
          ]
        },
        {
          menuid: 5,
          icon: 'li-icon-xitongguanli',
          menuname: '用户管理模块',
          hasThird: null,
          url: null,
          menus: [
            {
              menuid: 51,
              icon: 'icon-cus-manage',
              menuname: '用户管理',
              hasThird: 'N',
              url: 'system/user',
              menus: null
            },
            {
              menuid: 52,
              icon: 'icon-news-manage',
              menuname: '角色管理',
              hasThird: 'N',
              url: 'system/Role',
              menus: null
            },
          ]
        },
        {
          menuid: 6,
          icon: 'li-icon-xitongguanli',
          menuname: '系统管理模块',
          hasThird: null,
          url: null,
          menus: [
            {
              menuid: 61,
              icon: 'icon-cus-manage',
              menuname: '日志管理',
              hasThird: 'N',
              url: 'system/log',
              menus: null
            },
          ]
        },
      ],
      msg: 'success'
    }
          this.allmenu = res.data
    menu(localStorage.getItem('logintoken'))
      .then(res => {
        console.log(JSON.stringify(res))
        if (res.success) {
          this.allmenu = res.data
        } else {
          this.$message.error(res.msg)
          return false
        }
      })
      .catch(err => {
        this.$message.error('数据加载失败，请稍后再试！')
      })
    // 监听
    this.$root.Bus.$on('toggle', value => {
      this.collapsed = !value
    })
  }
}
</script>
<style>
.el-menu-vertical-demo:not(.el-menu--collapse) {
  width: 305px;
  min-height: 400px;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
  border: none;
  text-align: left;
}
.el-menu-item-group__title {
  padding: 0px;
}
.el-menu {
  border: none;
}
.logobox {
  height: 40px;
  line-height: 40px;
  color: #9d9d9d;
  font-size: 20px;
  text-align: center;
  padding: 20px 0px;
}
.logoimg {
  height: 40px;
}
</style>
 <!--  用户管理 -->
<template>
  <div>
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>用户管理</el-breadcrumb-item>
    </el-breadcrumb> 
    <!-- 搜索筛选 -->
    <el-form :inline="true" :model="uerInline" class="user-search">
      <el-form-item label="">
        <el-input size="small" v-model="uerInline.userName" placeholder="输入用户名"></el-input>
      </el-form-item>
       <el-form-item label="">
        <el-input size="small" v-model="uerInline.userMobile" placeholder="输入手机号"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button size="small" type="primary" icon="el-icon-search" @click="search">搜索</el-button>
        <el-button size="small" type="primary" icon="el-icon-plus" @click="userEdit()">添加</el-button>
      </el-form-item>
    </el-form>
    <!--列表-->
    <el-table size="small" @selection-change="selectChange" :data="userData" highlight-current-row v-loading="loading" border element-loading-text="数据加载中" style="width: 100%;">
      <el-table-column align="center" type="selection" width="50">
      </el-table-column>
      <el-table-column align="center" sortable prop="userName" label="用户名" width="120">
      </el-table-column>
      <el-table-column align="center" sortable prop="userRole" label="角色" width="180">
      </el-table-column>
      <el-table-column align="center" sortable prop="userMobile" label="手机号" width="120">
      </el-table-column>
      <el-table-column align="center" sortable prop="userSex" label="性别" min-width="50">
      </el-table-column>
      <el-table-column align="center" sortable prop="userEmail" label="邮箱" min-width="120">
      </el-table-column>
      <el-table-column align="center" sortable prop="editTime" label="最后登录时间" min-width="120">
        <template slot-scope="scope">
          <div>{{scope.row.editTime}}</div>
        </template>
      </el-table-column>
      <el-table-column align="center" sortable prop="isLock" label="操作状态" min-width="50">
        <template slot-scope="scope">
          <el-switch v-model="scope.row.isLock=='N'?nshow:fshow" active-color="#13ce66" inactive-color="#ff4949" @change="editType(scope.$index, scope.row)">
          </el-switch>
        </template>
      </el-table-column>
      <el-table-column align="center"  label="操作" width="300">
        <template slot-scope="scope">
          <el-button size="mini" @click="userEdit(scope.$index, scope.row)">编辑</el-button>
          <el-button size="mini" type="danger" @click="delUser(scope.$index, scope.row)">删除</el-button>
          <el-button size="mini" type="primary" @click="resetpwd(scope.$index, scope.row)">重置密码</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件 -->
    <Pagination v-bind:child-msg="pagination" @callFather="callFather"></Pagination>
    <!-- 编辑界面 -->
    <el-dialog :title="title" :visible.sync="userFormVisible" width="30%" @click='closeUser("edit")'>
      <el-form label-width="80px" ref="userForm" :model="userForm" :rules="rules">
        <el-form-item label="用户名" prop="userName">
          <el-input size="small" v-model="userForm.userName" auto-complete="off" placeholder="请输入用户名"></el-input>
        </el-form-item>
        <el-form-item label="角色" prop="userRole">
          <el-input size="small" v-model="userForm.userRole" auto-complete="off" placeholder="请输入姓名"></el-input>
        </el-form-item>
        <el-form-item label="手机号" prop="userMobile">
          <el-input size="small" v-model="userForm.userMobile" placeholder="请输入手机号"></el-input>
        </el-form-item>
        <el-form-item label="邮件" prop="userEmail">
          <el-input size="small" v-model="userForm.userEmail" placeholder="请输入邮箱地址"></el-input>
        </el-form-item>
        <el-form-item label="性别" prop="userSex">
          <el-radio v-model="userForm.userSex" label="男">男</el-radio>
          <el-radio v-model="userForm.userSex" label="女">女</el-radio>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" @click='closeUser("edit")'>取消</el-button>
        <el-button size="small" type="primary" :loading="loading" class="title" @click="submitForm('userForm')">保存</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
// 导入请求方法
import {
  userList,
  userSave,
  userDelete,
  userPwd,
  userExpireToken,
  userFlashCache,
  userLock,
  UserDeptTree,
  UserDeptSave,
  UserDeptdeptTree,
  UserChangeDept
} from '../../api/userMG'
import Pagination from '../../components/Pagination'
export default {
  data() {
    return {
      nshow: true, //switch开启
      fshow: false, //switch关闭
      loading: false, //是显示加载
      title: '添加用户',
      userFormVisible: false, //控制编辑页面显示与隐藏
      // 编辑与添加
      userForm: {
        userId: '',
        userName: '',
        userRole: '',
        roleId: '',
        userMobile: '',
        userEmail: '',
        userSex: '',
        token: localStorage.getItem('logintoken')
      },
      // 参数
      unitparm: {
        userIds: '',
        deptId: '',
        deptName: ''
      },
      // 选择数据
      selectdata: [],
      // rules表单验证
      rules: {
        userName: [
          { required: true, message: '请输入用户名', trigger: 'blur' }
        ],
        userRole: [
          { required: true, message: '请输入姓名', trigger: 'blur' }
        ],
        roleId: [{ required: true, message: '请选择角色', trigger: 'blur' }],
        userMobile: [
          { required: true, message: '请输入手机号', trigger: 'blur' },
          {
            pattern: /^1(3\d|47|5((?!4)\d)|7(0|1|[6-8])|8\d)\d{8,8}$/,
            required: true,
            message: '请输入正确的手机号',
            trigger: 'blur'
          }
        ],
        userEmail: [
          { required: true, message: '请输入邮箱', trigger: 'blur' },
          {
            pattern: /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
            required: true,
            message: '请输入正确的邮箱',
            trigger: 'blur'
          }
        ],
        userSex: [{ required: true, message: '请选择性别', trigger: 'blur' }]
      },
      // 删除用户
      seletedata: {
        ids: '',
        token: localStorage.getItem('logintoken')
      },
      // 重置密码
      resetpsd: {
        userId: '',
        token: localStorage.getItem('logintoken')
      },
      // 请求数据参数
      uerInline: {
        page: 1,
        limit: 10,
        deptId: '',
        userName: '',
        userMobile: '',
        isLock: ''
      },
      //用户数据
      userData: [],
      // 数据权限
      UserDept: [],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      // 选中
      checkmenu: [],
      //参数role
      saveroleId: '',
      // 分页参数
      pagination: {
        currentPage: 1,
        pageSize:5,
        total:5
      }
    }
  },
  // 注册组件
  components: {
    Pagination
  },
  watch: {},
  created() {
    this.getdata(this.uerInline)
  },
  methods: {
    // 获取数据方法
    getdata(parameter) {
      this.loading = true
      //测试环境使用数据
      let res = {
        code: 0,
        msg: null,
        count:7,
        data: [
          {
            addUser: '1',
            editUser: '1',
            addTime: null,
            editTime: "2024年04月20日",
            userId: 1,
            systemNo: 'pmd',
            userName: 'admin',
            userPassword: '21232f297a57a5a743894a0e4a801fc3',
            userRole: '系统管理员',
            userSex: '男',
            userMobile: '188-xxxx-xxxx',
            userEmail: 'admin@example.com',
            isLock: 'N',
            deptId: 1,
            deptName: 'xxxx',
            roleId: 1
          },
          {
            addUser: '2',
            editUser: '2',
            addTime: null,
            editTime: "2024年04月05日",
            userId: 2,
            systemNo: 'mc',
            userName: 'test',
            userPassword: 'd41d8cd98f00b204e9800998ecf8427e',
            userRole: '管理员',
            userSex: '女',
            userMobile: '159-xxxx-xxxx',
            userEmail: 'test@example.com',
            isLock: 'N',
            deptId: 2,
            deptName: 'xxxx',
            roleId: 2
          },
          {
            addUser: '3',
            editUser: '3',
            addTime: null,
            editTime: "2024年04月15日",
            userId: 3,
            systemNo: 'ec',
            userName: '梦境引导者',
            userPassword: '670b14728ad9902aecba32e2cfb72f03',
            userRole: '数字虚拟人专员',
            userSex: '男',
            userMobile: '188-xxxx-xxxx',
            userEmail: 'mingjing@example.com',
            isLock: 'N',
            deptId: 3,
            deptName: 'xxxx',
            roleId: 3
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1526275128000,
            editTime: "2024年04月20日",
            userId: 4,
            systemNo: null,
            userName: '星语聆听者',
            userPassword: 'e4d909c290d0fb1ca068ffaddf22cbd0',
            userRole: '高级数字虚拟人',
            userSex: '男',
            userMobile: '178-xxxx-xxxx',
            userEmail: 'starlistener@example.com',
            isLock: 'N',
            deptId: 4,
            deptName: 'zxxxxx',
            roleId: 4
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1526275128000,
            editTime: "2024年04月20日",
            userId: 5,
            systemNo: null,
            userName: '诗意对话者',
            userPassword: '03ac674216f3e15c761ee1a5e255f01f',
            userRole: '数字虚拟人主管',
            userSex: '女',
            userMobile: '135-xxxx-xxxx',
            userEmail: 'poeticchatter@example.com',
            isLock: 'N',
            deptId: 5,
            deptName: 'zxxxxx',
            roleId: 4
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1526275128000,
            editTime: "2024年04月19日",
            userId: 6,
            systemNo: null,
            userName: '心声解读者',
            userPassword: '827ccb0eea8a706c4c34a16891f84e7b',
            userRole: '数字虚拟人顾问',
            userSex: '女',
            userMobile: '176-xxxx-xxxx',
            userEmail: 'voiceinterpreter@example.com',
            isLock: 'N',
            deptId: 6,
            deptName: 'zxxxxx',
            roleId: 4
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1526275128000,
            editTime: "2024年04月20日",
            userId: 7,
            systemNo: null,
            userName: '时光倾听者',
            userPassword: 'a87ff679a2f3e71d9181a67b7542122c',
            userRole: '数字虚拟人代表',
            userSex: '男',
            userMobile: '132-xxxx-xxxx',
            userEmail: 'timelistener@example.com	',
            isLock: 'N',
            deptId: 7,
            deptName: 'zxxxxx',
            roleId: 4
          },
        ]
      }
      this.loading = false
      this.userData = res.data
      // 分页赋值
      this.pagination.currentPage = this.uerInline.page
      this.pagination.pageSize = this.uerInline.limit
      this.pagination.total = res.count
      // 测试环境  模拟数据结束  
      /***
       *  正式环境环境 调用接口
       */
      // 获取用户列表
      userList(parameter).then(res => {
        this.loading = false
        if (res.success == false) {
          this.$message({
            type: 'info',
            message: res.msg
          })
        } else {
          this.userData = res.data
          // 分页赋值
          this.pagination.currentPage = this.uerInline.page
          this.pagination.pageSize = this.uerInline.limit
          this.pagination.total = res.count
        }
      })
    },
    // 分页插件事件
    callFather(parm) {
      this.uerInline.page = parm.currentPage
      this.uerInline.limit = parm.pageSize
      this.getdata(this.uerInline)
    },
    //搜索事件
    search() {
      this.getdata(this.uerInline)
    },
    // 修改type
    editType: function(index, row) {
      this.loading = true
      let parm = {
        lock: '',
        userId: '',
        token: localStorage.getItem('logintoken')
      }
      parm.userId = row.userId
      let lock = row.isLock
      if (lock == 'N') {
        parm.lock = 'Y'
      } else {
        parm.lock = 'N'
      }
      // 修改状态
      userLock(parm).then(res => {
        this.loading = false
        if (res.success == false) {
          this.$message({
            type: 'info',
            message: res.msg
          })
        } else {
          this.$message({
            type: 'success',
            message: '状态修改成功'
          })
          this.getdata(this.uerInline)
        }
      })
    },
    //显示编辑界面
    userEdit: function(index, row) {
      this.userFormVisible = true
      if (row != undefined && row != 'undefined') {
        this.title = '修改用户'
        this.userForm.userId = row.userId
        this.userForm.userName = row.userName
        this.userForm.userRole = row.userRole
        this.userForm.roleId = row.roleId
        this.userForm.userMobile = row.userMobile
        this.userForm.userEmail = row.userEmail
        this.userForm.userSex = row.userSex
      } else {
        this.title = '添加用户'
        this.userForm.userId = ''
        this.userForm.userName = ''
        this.userForm.userRole = ''
        this.userForm.roleId = ''
        this.userForm.userMobile = ''
        this.userForm.userEmail = ''
        this.userForm.userSex = ''
      }
    },
    // 编辑、添加提交方法
    submitForm(editData) {
      this.$refs[editData].validate(valid => {
        if (valid) {
          // 请求方法
          userSave(this.userForm)
            .then(res => {
              this.userFormVisible = false
              this.loading = false
              if (res.success) {
                this.getdata(this.uerInline)
                this.$message({
                  type: 'success',
                  message: '用户保存成功！'
                })
              } else {
                this.$message({
                  type: 'info',
                  message: res.msg
                })
              }
            })
            .catch(err => {
              this.userFormVisible = false
              this.loading = false
              this.$message.error('用户保存失败，请稍后再试！')
            })
        } else {
          return false
        }
      })
    },
    handleClick(data, checked, node) {
      if (checked) {
        this.$refs.tree.setCheckedNodes([])
        this.$refs.tree.setCheckedNodes([data])
        this.unitparm.deptId = data.id
        this.unitparm.deptName = data.name
        //交叉点击节点
      } else {
      }
    },
    closeUser(dialog) {
        this.userFormVisible = false
    },
    // 重置密码
    resetpwd(index, row) {
      this.resetpsd.userId = row.userId
      this.$confirm('确定要重置用户密码吗?', '重置密码', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          userPwd(this.resetpsd)
            .then(res => {
              if (res.success) {
                this.$message({
                  type: 'success',
                  message: '重置用户密码成功！'
                })
                this.getdata(this.uerInline)
              } else {
                this.$message({
                  type: 'info',
                  message: res.msg
                })
              }
            })
            .catch(err => {
              this.loading = false
              this.$message.error('重置用户密码失败，请稍后再试！')
            })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '取消重置用户密码！'
          })
        })
    },
  }
}
</script>
<style scoped>
.user-search {
  margin-top: 20px;
}
.userRole {
  width: 100%;
}
</style>
 <!-- 角色管理 -->
<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>角色权限管理</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 搜索筛选 -->
    <el-form :inline="true" :model="uerInline" class="user-search">
      <el-form-item label="搜索：">
        <el-input size="small" v-model="uerInline.roleName" placeholder="输入角色权限名称"></el-input>
      </el-form-item>
      <el-form-item label="">
        <el-input size="small" v-model="uerInline.roleNo" placeholder="输入角色权限代码"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button size="small" type="primary" icon="el-icon-search" @click="search">搜索</el-button>
        <el-button size="small" type="primary" icon="el-icon-plus" @click="handleEdit()">添加</el-button>
      </el-form-item>
    </el-form>
    <!--列表-->
    <el-table size="small" :data="listData" highlight-current-row v-loading="loading" border element-loading-text="拼命加载中" style="width: 100%;">
      <el-table-column align="center" type="selection" width="60">
      </el-table-column>
      <el-table-column sortable prop="roleName" label="角色权限名称" width="300">
      </el-table-column>
      <el-table-column sortable prop="roleNo" label="角色权限代码" width="300">
      </el-table-column>
      <el-table-column sortable prop="editTime" label="修改时间" width="300">
        <template slot-scope="scope">
          <div>{{scope.row.editTime}}</div>
        </template>
      </el-table-column>
      <el-table-column sortable prop="editUser" label="修改人" width="300">
      </el-table-column>
      <el-table-column align="center" label="操作" min-width="300">
        <template slot-scope="scope">
          <el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
          <el-button size="mini" type="danger" @click="delUserRoleRole(scope.$index, scope.row)">删除</el-button>
          <el-button size="mini" type="primary"  @click="menuAccess(scope.$index, scope.row)">菜单权限</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件 -->
    <Pagination v-bind:child-msg="page" @callFather="callFather"></Pagination>
    <!-- 编辑界面 -->
    <el-dialog :title="title" :visible.sync="editFormVisible" width="30%" @click='closeDialog("edit")'>
      <el-form label-width="120px" :model="editForm" ref="editForm" :rules="rules">
        <el-form-item label="系统编码" prop="systemNo">
          <el-input size="small" v-model="editForm.systemNo" auto-complete="off" placeholder="请输入系统编码"></el-input>
        </el-form-item>
        <el-form-item label="角色权限名称" prop="roleName">
          <el-input size="small" v-model="editForm.roleName" auto-complete="off" placeholder="请输入角色权限名称"></el-input>
        </el-form-item>
        <el-form-item label="角色权限代码" prop="roleNo">
          <el-input size="small" v-model="editForm.roleNo" auto-complete="off" placeholder="请输入角色权限代码"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" @click='closeDialog("edit")'>取消</el-button>
        <el-button size="small" type="primary" :loading="loading" class="title" @click="submitForm('editForm')">保存</el-button>
      </div>
    </el-dialog>
    <!-- 菜单权限 -->
    <el-dialog title="菜单权限" :visible.sync="menuAccessshow" width="30%" @click='closeDialog("perm")'>
      <el-tree ref="tree" default-expand-all="" :data="RoleRight" :props="RoleRightProps" :default-checked-keys="checkmenu" node-key="id" show-checkbox>
      </el-tree>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" @click='closeDialog("perm")'>取消</el-button>
        <el-button size="small" type="primary" :loading="loading" class="title" @click="menuSubmit">保存</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import {
  roleList,
  roleSave,
  roleDelete,
  rolePwd,
  RoleRightTree,
  RoleRightSave
} from '../../api/userMG'
import Pagination from '../../components/Pagination'
export default {
  data() {
    return {
      nshow: true, //switch开启
      fshow: false, //switch关闭
      loading: false, //是显示加载
      editFormVisible: false, //控制编辑页面显示与隐藏
      menuAccessshow: false, //控制数据权限显示与隐藏
      title: '添加',
      editForm: {
        roleId: '',
        systemNo: '',
        roleNo: '',
        roleName: '',
        token: localStorage.getItem('logintoken')
      },
      // rules 表单验证
      rules: {
        systemNo: [
          { required: true, message: '请输入系统编码', trigger: 'blur' }
        ],
        roleNo: [
          { required: true, message: '请输入角色权限代码', trigger: 'blur' }
        ],
        roleName: [
          { required: true, message: '请输入角色权限名称', trigger: 'blur' }
        ]
      },
      uerInline: {
        page: 1,
        limit: 10,
        varLable: '',
        varName: '',
        token: localStorage.getItem('logintoken')
      },
      // 删除
      seletedata: {
        ids: '',
        token: localStorage.getItem('logintoken')
      },
      userparm: [], //搜索权限
      listData: [], //用户数据
      // 数据权限
      RoleRight: [],
      RoleRightProps: {
        children: 'children',
        label: 'name'
      },
      // 选中
      checkmenu: [],
      //参数role
      saveroleId: '',
      // 分页参数
      page: {
        currentPage: 1,
        pageSize: 10,
        total: 10
      }
    }
  },
  // 注册组件
  components: {
    Pagination
  },
  created() {
    this.getRolePermissionData(this.uerInline)
  },
  methods: {
    // 获取角色权限列表
    getRolePermissionData(parameter) {
      // 模拟数据
      let res = {
        code: 0,
        msg: null,
        count: 5,
        data: [
          {
            addUser: 'admin',
            editUser: 'admin',
            addTime: 1519182004000,
            editTime: '2024年03月15日',
            roleId: 1,
            systemNo: 'pmd',
            roleNo: 'role001',
            roleName: '系统管理员'
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1521111376000,
            editTime:'2024年03月15日',
            roleId: 2,
            systemNo: 'order',
            roleNo: 'role002',
            roleName: '管理员'
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1520678221000,
            editTime: '2024年03月18日',
            roleId: 3,
            systemNo: 'pm',
            roleNo: 'role003',
            roleName: '数字虚拟人专员'
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1520678221000,
            editTime: '2024年03月19日',
            roleId: 4,
            systemNo: 'pm',
            roleNo: 'role004',
            roleName: '高级数字虚拟人'
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1520678221000,
            editTime: '2024年03月20日',
            roleId: 5,
            systemNo: 'pm',
            roleNo: 'role005',
            roleName: '数字虚拟人主管'
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1520678221000,
            editTime: '2024年03月20日',
            roleId: 6,
            systemNo: 'pm',
            roleNo: 'role006',
            roleName: '数字虚拟人顾问'
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1520678221000,
            editTime: '2024年03月20日',
            roleId: 7,
            systemNo: 'pm',
            roleNo: 'role007',
            roleName: '数字虚拟人代表'
          },
        ]
      }
      this.loading = false
      this.listData = res.data
      // 分页赋值
      this.page.currentPage = this.uerInline.page
      this.page.pageSize = this.uerInline.limit
      this.page.total = res.count
      // 测试环境  模拟数据结束  
      /***
       *  正式环境环境 调用接口
       */
      roleList(parameter)
        .then(res => {
          this.loading = false
          if (res.success == false) {
            this.$message({
              type: 'info',
              message: res.msg
            })
          } else {
            this.listData = res.data
            // 分页赋值
            this.page.currentPage = this.uerInline.page
            this.page.pageSize = this.uerInline.limit
            this.page.total = res.count
          }
        })
        .catch(err => {
          this.loading = false
          this.$message.error('获取角色权限列表失败，请稍后再试！')
        })
    },
    // 分页
    callFather(parm) {
      this.uerInline.page = parm.currentPage
      this.uerInline.limit = parm.pageSize
      this.getRolePermissionData(this.uerInline)
    },
    // 搜索事件
    search() {
      this.getRolePermissionData(this.uerInline)
    },
    //修改 添加
    handleEdit: function(index, row) {
      this.editFormVisible = true
      if (row != undefined && row != 'undefined') {
        this.title = '修改'
        this.editForm.roleId = row.roleId
        this.editForm.systemNo = row.systemNo
        this.editForm.roleNo = row.roleNo
        this.editForm.roleName = row.roleName
      } else {
        this.title = '添加'
        this.editForm.roleId = ''
        this.editForm.systemNo = ''
        this.editForm.roleNo = ''
        this.editForm.roleName = ''
      }
    },
    // 保存方法
   submiRoletForm(editData) {
      this.$refs[editData].validate(valid => {
        if (valid) {
          roleSave(this.editForm)
            .then(res => {
              this.editFormVisible = false
              this.loading = false
              if (res.success) {
                this.getRolePermissionData(this.uerInline)
                this.$message({
                  type: 'success',
                  message: '角色保存成功！'
                })
              } else {
                this.$message({
                  type: 'info',
                  message: res.msg
                })
              }
            })
            .catch(err => {
              this.editFormVisible = false
              this.loading = false
              this.$message.error('角色保存失败，请稍后再试！')
            })
        } else {
          return false
        }
      })
    },
    // 删除角色权限
    delUserRole(index, row) {
      this.$confirm('确定要删除角色嘛?', '信息', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          roleDelete(row.roleId)
            .then(res => {
              if (res.success) {
                this.$message({
                  type: 'success',
                  message: '角色已删除！'
                })
                this.getRolePermissionData(this.uerInline)
              } else {
                this.$message({
                  type: 'info',
                  message: res.msg
                })
              }
            })
            .catch(err => {
              this.loading = false
              this.$message.error('角色删除失败，请稍后再试！')
            })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
        })
    },
    // 数据权限
    menuAccess: function(index, row) {
      this.menuAccessshow = true
      this.saveroleId = row.roleId
      RoleRightTree(row.roleId)
        .then(res => {
          if (res.data.success) {
            this.$message({
              type: 'success',
              message: '获取角色成功'
            })
            this.RoleRight = this.changeArr(res.data.data)
          } else {
            this.$message({
              type: 'info',
              message: res.data.msg
            })
          }
        })
        .catch(err => {
          this.loading = false
          this.$message.error('获取角色失败，请稍后再试！')
        })
    },
    // tree 递归
    changeArr(list) {
      var temptree = [],
        tree = [],
        items = []
      for (var i in list) {
        if (!temptree[list[i].id]) {
          var trow = {
            id: list[i].id,
            pId: list[i].pId,
            name: list[i].name,
            open: list[i].open,
            checked: list[i].checked,
            children: []
          }
          temptree[list[i].id] = trow
          items.push(trow)
        }
        if (list[i].uid > 0) {
          temptree[list[i].id]['children'].push({
            id: list[i].id,
            pId: list[i].pId,
            name: list[i].name,
            open: list[i].open,
            checked: list[i].checked,
            children: []
          })
        }
      }
      for (var j in items) {
        if (temptree[items[j].pId]) {
          temptree[items[j].pId]['children'].push(temptree[items[j].id])
        } else {
          tree.push(temptree[items[j].id])
        }
      }
      temptree = null
      items = null
      return tree
    },
    // 菜单权限-保存
    menuSubmit() {
      let parm = {
        roleId: this.saveroleId,
        moduleIds: ''
      }
      let node = this.$refs.tree.getCheckedNodes()
      let moduleIds = []
      if (node.length != 0) {
        for (let i = 0; i < node.length; i++) {
          moduleIds.push(node[i].id)
        }
        parm.moduleIds = JSON.stringify(moduleIds)
      }
      RoleRightSave(parm)
        .then(res => {
          if (res.success) {
            this.$message({
              type: 'success',
              message: '权限保存成功'
            })
            this.menuAccessshow = false
            this.getRolePermissionData(this.uerInline)
          } else {
            this.$message({
              type: 'info',
              message: res.msg
            })
          }
        })
        .catch(err => {
          this.loading = false
          this.$message.error('权限保存失败，请稍后再试！')
        })
    },
    // 关闭编辑、增加弹出框
    closeDialog(dialog) {
      if (dialog == 'edit') {
        this.editFormVisible = false
      } else if (dialog == 'perm') {
        this.menuAccessshow = false
      }
    }
  }
}
</script>
 <!--  日志管理 -->
<template>
  <div>
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>日志管理</el-breadcrumb-item>
    </el-breadcrumb> 
    <div class="log-list">  
    <el-container>  
      <el-header>  
        <el-input  
          placeholder="请输入关键词搜索"  
          v-model="searchKeyword"  
          clearable  
          @clear="handleClear"  
          @input="handleSearch"  
        >  
          <el-button slot="append" icon="el-icon-search"></el-button>  
        </el-input>  
      </el-header>  
      <el-main>  
        <el-table  
          :data="filteredLogs"  
          style="width: 100%"  
          @sort-change="handleSortChange"  
        >  
          <el-table-column  
            prop="time"  
            label="时间"  
            sortable  
            width="180"  
          ></el-table-column>  
          <el-table-column  
            prop="level"  
            label="日志级别"  
            width="100"  
          ></el-table-column>  
          <el-table-column  
            prop="message"  
            label="日志信息"  
          ></el-table-column>  
          <el-table-column  
            prop="source"  
            label="来源"  
            width="200"  
          ></el-table-column>  
          <el-table-column  
            label="操作"  
            width="120"  
          >  
            <template slot-scope="scope">  
              <el-button type="text" @click="handleDetail(scope.$index, scope.row)">详情</el-button>  
            </template>  
          </el-table-column>  
        </el-table>  
        <el-pagination  
          @size-change="handleSizeChange"  
          @current-change="handleCurrentChange"  
          :current-page="currentPage"  
          :page-sizes="[10, 20, 50, 100]"  
          :page-size="pageSize"  
          layout="total, sizes, prev, pager, next, jumper"  
          :total="totalLogs"  
        ></el-pagination>  
      </el-main>  
    </el-container>  
  </div>  
  </div>
</template>
<script>
import Pagination from '../../components/Pagination'
export default {
  data() {
    return {
      searchKeyword: '',  
      logs: [], // 假设这是从后端获取的原始日志数据  
      filteredLogs: [], // 根据搜索和排序过滤后的日志数据  
      currentPage: 1,  
      pageSize: 10,  
      totalLogs: 20,  
      sort: {  
        prop: 'timestamp',  
        order: 'descending',  
      },  
    }
  },
  // 注册组件
  components: {
    Pagination
  },
  computed: {  
    // 根据搜索关键词和排序对日志进行过滤  
    filteredLogsComputed() {  
      const { searchKeyword, sort } = this;  
      let filtered = [...this.logs];  
      if (searchKeyword) {  
        filtered = filtered.filter(log =>  
          log.message.includes(searchKeyword) ||  
          log.source.includes(searchKeyword)  
        );  
      }  
      if (sort.prop && sort.order) {  
        filtered.sort((a, b) => {  
          if (a[sort.prop] < b[sort.prop]) return sort.order === 'ascending' ? -1 : 1;  
          if (a[sort.prop] > b[sort.prop]) return sort.order === 'ascending' ? 1 : -1;  
          return 0;  
        });  
      }  
      return filtered.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize);  
    },  
  },  
  watch: {  
    // 监听搜索关键词变化，实时过滤日志  
    searchKeyword(newVal) {  
      this.filteredLogs = this.filteredLogsComputed;  
    },  
    // 监听排序变化，实时过滤日志  
    sort: {  
      handler(newVal) {  
        this.filteredLogs = this.filteredLogsComputed;  
      },  
      deep: true,  
    }, 
 // 监听当前页码变化  
    currentPage(newVal) {  
      this.filteredLogs = this.filteredLogsComputed;  
    },  
    // 监听每页显示数量变化  
    pageSize(newVal) {  
      this.currentPage = 1; // 当每页显示数量变化时，通常回到第一页  
      this.filteredLogs = this.filteredLogsComputed;  
    },  
    // 监听原始日志数据变化 
    logs(newVal) {  
      // this.totalLogs = newVal.length;  
      this.filteredLogs = this.filteredLogsComputed;  
    }  
  },  
  // 在组件创建时获取日志数据  
  created() {  
      this.fetchLogs();  
    },
  methods: {  
    // 处理搜索输入  
    handleSearch() {  
      this.currentPage = 1; // 当搜索时，通常回到第一页  
      this.filteredLogs = this.filteredLogsComputed;  
    },  
    // 清除搜索关键词  
    handleClear() {  
      this.searchKeyword = '';  
      this.handleSearch();  
    },  
    // 处理排序变化  
    handleSortChange({ prop, order }) {  
      this.sort = { prop, order };  
    },  
    // 处理每页显示数量变化  
    handleSizeChange(val) {  
      this.pageSize = val;  
    },  
    // 处理当前页码变化  
    handleCurrentChange(val) {  
      this.currentPage = val;  
    },  
    // 处理日志详情查看  
    handleDetail(index, row) {  
      this.$message.info(row)
    },  
    //获取日志数据  
    fetchLogs() {  
      //测试环境
      this.logs= [  
      {  
        time: '2024-04-01 10:00:00',  
        level: 'INFO',  
        message: '系统已启动。',  
        source: '服务器启动脚本'  
      },  
      {  
        time: '2024-04-01 10:05:15',  
        level: 'WARN',  
        message: '用户登录失败，密码错误3次。',  
        source: '用户认证模块'  
      },  
      {  
        time: '2024-04-01 10:15:30',  
        level: 'DEBUG',  
        message: '接收到API请求，处理中...',  
        source: 'API服务层'  
      },  
      {  
        time: '2024-04-01 10:20:45',  
        level: 'INFO',  
        message: '数据更新成功。',  
        source: '数据库操作模块'  
      },  
      {  
        time: '2024-04-01 10:30:00',  
        level: 'ERROR',  
        message: '文件上传失败，磁盘空间不足。',  
        source: '文件处理服务'  
      },  
      {  
        time: '2024-04-01 10:40:15',  
        level: 'WARN',  
        message: '订单状态异常，请检查。',  
        source: '订单处理服务'  
      },  
      {  
        time: '2024-04-01 10:50:30',  
        level: 'INFO',  
        message: '邮件发送成功。',  
        source: '邮件发送服务'  
      },  
      {  
        time: '2024-04-01 11:00:45',  
        level: 'DEBUG',  
        message: '缓存数据更新。',  
        source: '缓存管理模块'  
      },  
      {  
        time: '2024-04-01 11:10:00',  
        level: 'INFO',  
        message: '系统定时任务执行完毕。',  
        source: '任务调度模块'  
      },  
      {  
        time: '2024-04-01 11:15:15',  
        level: 'WARN',  
        message: '第三方接口调用超时，请重试。',  
        source: '外部接口调用服务'  
      }  
      ]  
      this.totalLogs = 51;
      // //正式环境 
      axios.get('/api/logs')  
        .then(response => {  
          this.logs = response.data;  
          this.totalLogs = response.totalLogs;
        })  
        .catch(error => {  
          console.error('获取日志数据失败:', error);  
        });  
    },  
  }
}
</script>
<style scoped>
.user-search {
  margin-top: 20px;
}
.userRole {
  width: 100%;
}
.log-list{
  margin-top: 30px;
}
</style>
<!-- 虚拟人创建与定制 -->
<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>虚拟人创建与定制</el-breadcrumb-item>
    </el-breadcrumb>
    <div class="virtual-creator">  
    <el-container>  
      <el-main>  
        <el-row :gutter="20">  
          <el-col :span="12">  
            <div class="creator-panel">  
              <h2>形象设计</h2>  
              <el-form ref="designForm" :model="designModel" label-width="120px">  
                <el-form-item label="面部特征">  
                  <el-input v-model="designModel.faceFeatures"></el-input>  
                </el-form-item>  
                <el-form-item label="虚拟人的年龄">  
                  <el-input v-model="designModel.age"></el-input>  
                </el-form-item>  
                <el-form-item label="发型">  
                  <el-select v-model="designModel.hairStyle" placeholder="请选择发型">  
                    <el-option  
                      v-for="item in hairStyles"  
                      :key="item.value"  
                      :label="item.label"  
                      :value="item.value">  
                    </el-option>  
                  </el-select>  
                </el-form-item>  
                <el-form-item label="服装">  
                  <el-select v-model="designModel.clothing" placeholder="请选择服装">  
                    <el-option  
                      v-for="item in clothingStyles"  
                      :key="item.value"  
                      :label="item.label"  
                      :value="item.value">  
                    </el-option>  
                  </el-select>    
                </el-form-item>  
                <el-form-item>  
                  <el-button type="primary" @click="createVirtualPerson">创建虚拟人</el-button>  
                </el-form-item>  
              </el-form>  
            </div>  
          </el-col>  
          <el-col :span="12">  
            <div class="preview-panel">  
              <h2>预览与定制</h2>  
              <div class="preview-area">  
                <!--展示虚拟人的3D预览图 -->  
                <img :src="previewImage" alt="虚拟人预览" />  
              </div>  
              <el-button type="text" @click="editVirtualPerson">编辑虚拟人</el-button>  
            </div>  
          </el-col>  
        </el-row>  
      </el-main>  
    </el-container>
    </div>  
  </div>
</template>
<script>
export default {
  data() {
    return {
      designModel: {  
        name: '', // 虚拟人的名字  
      gender: 'male', // 虚拟人的性别，可以是 'male' 或 'female'  
      age: 25, // 虚拟人的年龄  
      hairColor: 'black', // 虚拟人的头发颜色  
      eyeColor: 'brown', // 虚拟人的眼睛颜色  
      skinTone: 'light', // 虚拟人的肤色  
      facialFeatures: { // 虚拟人的面部特征  
        noseType: 'normal', // 鼻子类型  
        mouthShape: 'smile', // 嘴巴形状  
        eyeShape: 'round', // 眼睛形状  
      },  
      clothing: { // 虚拟人的服装  
        shirtColor: 'blue', // 衬衫颜色  
        pantsColor: 'black', // 裤子颜色  
        shoeType: 'sneakers', // 鞋子类型   
      },
      },
      hairStyles: [  
        { value: 'short', label: '短发' },  
        { value: 'long', label: '长发' }, 
        { value: 'juan', label: '卷发' },   
      ], 
      clothingStyles: [  
        { value: 'T', label: '白T' },  
        { value: 'shirt', label: '衬衫' }, 
        { value: 'shoe', label: '裙子' },   
      ],   
      // https://inews.gtimg.com/newsapp_bt/0/15252288421/1000
      previewImage: 'https://img2.baidu.com/it/u=1510805675,2542674489&fm=253&fmt=auto&app=138&f=JPEG?w=630&h=352',  
    }
  },
  created() {
    this.getdata(this.virtualInline)
  },
  methods: {
    async editVirtualPerson() {  
    try {  
      // 获取要编辑的虚拟人的ID  
      const virtualPersonId = this.virtualPersonToEdit.id;  
      // 验证表单数据  
      if (!this.validateEditForm()) {  
        this.$message.error('请填写完整的编辑信息！');  
        return;  
      }  
      // 准备要发送到后端的虚拟人数据  
      const updatedVirtualPersonData = {  
        ...this.editFormModel,  
      };  
      // 更新虚拟人  
      const response = await this.$axios.put(`/api/virtual-persons/${virtualPersonId}`, updatedVirtualPersonData);  
      // 处理响应  
      if (response.data.success) {  
        this.$message.success('虚拟人信息更新成功！');  
        const updatedVirtualPerson = response.data.data;  
        // 更新本地虚拟人数据  
        this.virtualPersonToEdit = updatedVirtualPerson;  
        // 清除表单数据  
        this.resetEditForm();  
      } else {  
        this.$message.error('虚拟人信息更新失败：' + response.data.message);  
      }  
    } catch (error) {  
      console.error('编辑虚拟人时发生错误：', error);  
      this.$message.error('网络错误，请稍后再试！');  
    }  
  },  
  validateEditForm() {  
    // 在这里实现表单验证逻辑  
    const virtualPersonId = this.virtualPersonToEdit.id;
    if (virtualPersonId&&this.designModel.age) {
      return true; 
    }
  },  
  resetEditForm() {  
    // 重置编辑表单数据到初始状态  
    this.$refs.editForm.resetFields();   
  },  
  }
}
</script>
<!-- 虚拟人交互模拟-->
<template>
  <div class="virtual-person">
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>虚拟人交互模拟</el-breadcrumb-item>
    </el-breadcrumb>
    <div class="virtual-person-interaction">  
    <el-form :model="virtualPerson" ref="virtualPersonForm" label-width="120px">  
      <!-- 基本信息 -->  
      <el-form-item label="姓名">  
        <el-input v-model="virtualPerson.name"></el-input>  
      </el-form-item>  
      <el-form-item label="状态">  
        <el-radio-group v-model="virtualPerson.status">  
          <el-radio label="active">活跃</el-radio>  
          <el-radio label="inactive">休眠</el-radio>  
        </el-radio-group>  
      </el-form-item>  
      <!-- 外观设置 -->  
      <el-form-item label="肤色">  
        <el-color-picker v-model="virtualPerson.skinColor"></el-color-picker>  
      </el-form-item>  
      <el-form-item label="发型">  
        <el-select v-model="virtualPerson.hairStyle">  
          <el-option label="短发" value="short"></el-option>  
          <el-option label="长发" value="long"></el-option>  
        </el-select>  
      </el-form-item>  
        <!-- 表情设置 -->  
        <el-form-item label="表情">  
          <el-radio-group v-model="virtualPerson.expression">  
            <el-radio label="happy">开心</el-radio>  
            <el-radio label="sad">伤心</el-radio>  
            <el-radio label="angry">生气</el-radio>  
          </el-radio-group>  
        </el-form-item>
      <!-- 交互设置 -->  
      <el-form-item label="动作">  
        <el-select v-model="selectedAction" placeholder="请选择动作">  
          <el-option v-for="action in actions" :key="action.value" :label="action.label" :value="action.value"></el-option>  
        </el-select>  
        <el-button @click="performAction">执行动作</el-button>  
      </el-form-item>  
      <el-form-item label="语音">  
        <el-input type="textarea" v-model="virtualPerson.speech"></el-input>  
        <el-button style="margin-top: 20px;" @click="speak">说话</el-button>  
        <el-alert style="margin-top: 20px;" v-if="speechBubble" type="success" show-icon :closable="false" :description="speechBubble"></el-alert>
      </el-form-item>  
      <!-- 虚拟人预览 -->  
       <div class="virtual-person-preview">  
        <img :src="virtualPerson.avatar" alt="虚拟人预览" />  
        <p>当前状态：{{ virtualPerson.status }}</p>  
      </div>  
    </el-form>  
  </div>  
  </div>
</template>
<script>
export default {
  data() {
    return {
      virtualPerson: {  
        name: '高级数字虚拟人',  
        status: 'active',  
        skinColor: '#FFFFFF',  
        hairStyle: 'short',  
        speech: '',  
        avatar: 'https://img2.baidu.com/it/u=1510805675,2542674489&fm=253&fmt=auto&app=138&f=JPEG?w=630&h=352', // 虚拟人默认图片 
        expression: 'happy',  
      },  
      actions: [  
        { label: '挥手', value: 'wave' },  
        { label: '跳舞', value: 'dance' }, 
        { label: '跑步', value: 'pao' },  
      ],  
      selectedAction: '',  
    }
  },
  created() {
  },
  methods: {
    performAction() {  
      //执行动作的逻辑
      console.log(`虚拟人执行了动作：${this.selectedAction}`);  
      if (this.selectedAction === 'wave') {  
        this.virtualPerson.expression = 'happy';  
      } else if (this.selectedAction === 'dance') {  
        this.virtualPerson.expression = 'sad';  
      } else{
        this.virtualPerson.expression = 'angry';  
      }
      // 重置选中动作  
      this.selectedAction = ''; 
    },  
    speak() {  
       // 处理虚拟人的说话逻辑   展示文字气泡
       this.speechBubble = `虚拟人说：${ this.virtualPerson.speech}`;  
      // 展示语音气泡一段时间后消失  
      setTimeout(() => {  
        this.speechBubble = '';  
      }, 3000);  
      // 清空输入框  
      this.virtualPerson.speech = '';   
    },
  },  
}
</script>
 <!-- 交互分析 -->
 <template>
  <div class="interaction-analysis">
    <el-container>
      <!-- <el-header>肇远数字虚拟人后台记录管理系统 - 虚拟人交互分析</el-header> -->
      <el-main>
        <!-- 图表展示区域 -->
        <div class="chart-container">
          <el-card class="box-card">
            <div slot="header" class="clearfix">
              <span>交互次数统计</span>
              <el-button style="float: right; padding: 3px 0" type="text"
                >查看更多</el-button
              >
            </div>
            <div v-if="chartDataLoaded">
              <!-- 这里放置ECharts图表组件 -->
              <div ref="myChart" style="width: 100%; height: 400px"></div>
            </div>
          </el-card>
        </div>
        <!-- 数据列表展示区域 -->
        <div class="data-list-container">
          <el-card class="box-card">
            <div slot="header" class="clearfix">
              <span>交互数据列表</span>
            </div>
            <el-table
              :data="analysis"
              style="width: 100%"
              @selection-change="handleSelectionChange"
            >
              <el-table-column type="selection" width="55"></el-table-column>
              <el-table-column
                prop="date"
                label="日期"
                width="280"
              ></el-table-column>
              <el-table-column
                prop="label"
                label="响应时间 (秒)"
                width="180"
              ></el-table-column>
              <el-table-column
                prop="interactions"
                label="交互次数"
                width="220"
              ></el-table-column>
              <el-table-column
                prop="satisfaction"
                label="满意度"
                width="220"
              ></el-table-column>
              <!-- 其他数据列 -->
            </el-table>
            <el-pageArguments
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
              :current-page="pageArguments.currentPage"
              :page-sizes="[10, 20, 50, 100]"
              :page-size="pageArguments.pageSize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="pageArguments.total"
            ></el-pageArguments>
          </el-card>
        </div>
      </el-main>
    </el-container>
  </div>
</template> 
<script type="text/ecmascript-6">
 import {analysisData,recordsISave,recordsIDelete } from '../../api/basisMG'
import Chart from "echarts";
export default {
  name: "InteractionAnalysis",
  data() {
    return {
      filters: {
        dateRange: "",
      },
      analysis: [], // 表格数据
      chartData: null, // 图表数据
      chartDataLoaded: true,
      pageArguments: {
        currentPage: 1,
        pageSize: 10,
        total: 0,
      },
      multipleSelection: [], // 表格多选数据
    };
  },
  created() {
    this.getdata();
  },
  mounted() {
    // 初始化图表
    this.AnalysisChart();
  },
  methods: {
    // 获取数据列表
    getdata(recordContent) {
      this.loading = true;
      // 模拟数据开始
      let res = {
        columns: [
          { name: "日期", label: "日期" },
          { name: "交互次数", label: "交互次数" },
          { name: "平均响应时间", label: "平均响应时间 (秒)" },
          { name: "满意度", label: "满意度 (%)" },
        ],
        data: [
        {date: "2023-04-10", interactions: 60, label: 5.0, satisfaction: 85 },
          {date: "2023-04-11", interactions: 63, label: 5.2, satisfaction: 90 },
          { date: "2023-04-12", interactions:78, label: 4.8, satisfaction: 88 },
          { date: "2023-04-13", interactions:81, label: 5.5, satisfaction: 92 },
          { date: "2023-04-14", interactions:59, label: 5.0, satisfaction: 87 },
          { date: "2023-04-15", interactions: 47, label: 4.9, satisfaction: 89 },
          { date: "2023-04-16", interactions: 42,label: 4.9, satisfaction:95 },
        ],
      };
      this.loading = false;
      this.analysis = res.data;
      /***
       *  正式环境环境 调用接口
       */
       this.getAnalysisData(); 
    },
    // 初始化图表
    AnalysisChart() {
      this.chartDataLoaded = true;
      const chartDom = this.$refs.myChart;
      const myChart = Chart.init(chartDom);
      // 设置图表配置项和数据
      const option = {
        // 标题
        title: {
          text: "肇远数字虚拟人交互分析",
          subtext: "交互次数与满意度",
          left: "center",
        },
        // 提示框组件
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "shadow",
          },
        },
        // 网格
        grid: {
          left: "3%",
          right: "4%",
          bottom: "3%",
          containLabel: true,
        },
        // x轴
        xAxis: {
          type: "category",
          data: [
            "2024-04-10",
            "2024-04-11",
            "2024-04-12",
            "2024-04-13",
            "2024-04-14",
            "2024-04-15",
            "2024-04-16",
          ], // 类别数据，
          axisLine: {
            lineStyle: {
              color: "#999999",
              width: 1
            }
          },
          axisLabel: {
            margin: 14,
            height: 70,
            interval: 0,
            textStyle: {
              fontSize: 10,
              color: "#999999"
            }
          }
        },
        // y轴
        yAxis: {
          type: "value",
        },
        // 系列列表
        series: [
          {
            name: "交互次数",
            type: "bar", // 柱状图
            data: [60, 63, 78, 81, 59,47, 42,], // 
             itemStyle: {
            normal: {
              color: "#FFB6C1",
              lineStyle: {
                color: "#FFB6C1",
              }
            }
          }
          },
          {
            name: "满意度",
            type: "line", // 折线图
            data: [85, 90, 88, 92, 87,89, 95,], // 满意度数据，
            itemStyle: {
            normal: {
              color: "#3299CC",
              lineStyle: {
                color: "#3299CC",
              }
            }
          }
          },
        ],
      };
      myChart.setOption(option);
    },
    // 获取数据
    getAnalysisData() {
      // 发送请求获取数据
      this.fetchInteractionData(this.filters.dateRange)
        .then((response) => {
          this.analysisData = response.analysisData;
          this.chartData = response.chartData;
          this.pageArguments.total = response.total;
          this.AnalysisChart(); // 如果有新的图表数据，重新初始化图表
        })
        .catch((error) => {
          console.error("Error fetching data:", error);
        });
    },
    // 处理表格多选数据变化
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    // 处理分页大小变化
    handleSizeChange(val) {
      this.pageArguments.pageSize = val;
      this.getAnalysisData(); // 重新获取数据
    },
    // 处理分页当前页变化
    handleCurrentChange(val) {
      this.pageArguments.currentPage = val;
      this.getAnalysisData(); // 重新获取数据
    },
  },
};
</script>
<!-- 交互记录 -->
<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>交互记录</el-breadcrumb-item>
    </el-breadcrumb>
    <div class="interaction-records-container" >
      <el-button class="addBtn" @click="dialogVisible = true">添加记录</el-button> 
      <!-- 添加记录弹出 -->
      <el-dialog  
      title="添加记录"  
      :visible.sync="dialogVisible"  
      width="50%"  
      @close="dialogVisible = false"  
    >  
      <el-form :model="form" ref="form" label-width="120px">  
        <el-form-item label="虚拟人ID">  
          <el-input v-model="form.virtualId"></el-input>  
        </el-form-item>  
        <el-form-item label="交互时间">  
          <el-date-picker  
            v-model="form.timestamp"  
            type="datetime"  
            placeholder="选择日期时间"  
          ></el-date-picker>  
        </el-form-item>  
        <el-form-item label="用户ID">  
          <el-input v-model="form.userId"></el-input>  
        </el-form-item>  
        <el-form-item label="交互类型">  
          <el-input v-model="form.interactionType"></el-input>  
        </el-form-item>  
        <el-form-item label="交互内容">  
          <el-input v-model="form.content"></el-input>  
        </el-form-item>  
        <el-form-item label="交互结果">  
          <el-input v-model="form.outcome"></el-input>  
        </el-form-item>  
      </el-form>  
      <span slot="footer" class="dialog-footer">  
        <el-button @click="dialogVisible = false">取消</el-button>  
        <el-button type="primary" @click="addRecordFromForm">确定</el-button>  
      </span>  
    </el-dialog>  
      <el-table :data="RecordList" style="width: 100%" border @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column prop="virtualId" label="虚拟人ID" width="120"></el-table-column>
        <el-table-column prop="timestamp" label="时间" width="180"></el-table-column>
        <el-table-column prop="userId" label="用户ID" width="180"></el-table-column>
        <el-table-column prop="interactionType" label="交互类型" width="120"></el-table-column>
        <el-table-column prop="content" label="交互内容" width="300"></el-table-column>
        <el-table-column prop="device" label="交互设备" width="100"></el-table-column>
        <el-table-column prop="location" label="交互地点" width="200"></el-table-column>
        <el-table-column prop="outcome" label="交互结果" width="300"></el-table-column>
        <el-table-column  align="center" label="操作">  
        <template slot-scope="scope">  
          <el-button type="danger" icon="el-icon-delete" @click="deleteRecord(scope.$index)">删除</el-button>  
        </template>  
      </el-table-column>  
      </el-table>
      <!-- 分页组件 -->
      <el-pagination background layout="prev, pager, next" :page-size="10" :total=" pageTion.total"
        @current-change="handlePageChange"></el-pagination>
    </div>
  </div>
</template>
<script>
 import {getRecords,recordsISave, recordDelete } from '../../api/basisMG'
import Pagination from '../../components/Pagination'
export default {
  data() {
    return {
      RecordList: [], //数据
      // 分页参数
      pageTion: {
        currentPage: 1,
        pageSize: 10,
        total: 10
      },
      dialogVisible: false,  
      form: {  
        virtualId: '',  
        timestamp: '',  
        userId: '',  
        interactionType: '',  
        content: '',  
        outcome: ''  
      },
    }
  },
  // 注册组件
  components: {
    Pagination
  },
  created() {
    this.getdata(this.pageTion)
  },
  methods: {
    // 获取数据列表
    getdata(recordContent) {
      this.loading = true
      // 模拟数据开始
      let res = {
        code: 0,
        msg: null,
        count: 41,
        data: [
          {
            id: 1,
            virtualId: 'virtual-1',
            timestamp: '2023-04-01 10:00:00',
            userId: 'user-A',
            interactionType: 'Chat',
            content: 'Hello, how are you?',
            device: 'Laptop',
            location: 'Office',
            outcome: 'Success'
          },
          {
            id: 2,
            virtualId: 'virtual-2',
            timestamp: '2023-04-01 10:15:00',
            userId: 'user-B',
            interactionType: 'Gesture',
            content: 'Waved goodbye',
            device: 'Smartphone',
            location: 'Cafe',
            outcome: 'Success'
          },
          {
            id: 3,
            virtualId: 'virtual-1',
            timestamp: '2023-04-01 10:30:00',
            userId: 'user-C',
            interactionType: 'VoiceCommand',
            content: 'Play music',
            device: 'Smart Speaker',
            location: 'Living Room',
            outcome: 'Error'
          },
          {
            id: 4,
            virtualId: 'virtual-3',
            timestamp: '2023-04-01 11:00:00',
            userId: 'user-A',
            interactionType: 'Chat',
            content: 'What is the weather today?', 
              device: 'Tablet',
            location: 'Outdoor',
            outcome: 'Success'
          },
          {
            id: 5,
            virtualId: 'virtual-2',
            timestamp: '2023-04-01 11:15:00',
            userId: 'user-D',
            interactionType: 'Gesture',
            content: 'Pointed to the screen',
            device: 'Desktop',
            location: 'Office',
            outcome: 'Success'
          },
          {
            id: 6,
            virtualId: 'virtual-1',
            timestamp: '2023-04-01 11:30:00',
            userId: 'user-B',
            interactionType: 'Chat',
            content: 'Need help with task',
            device: 'Laptop',
            location: 'Home Office',
            outcome: 'Pending'
          },
          {
            id: 7,
            virtualId: 'virtual-3',
            timestamp: '2023-04-01 12:00:00',
            userId: 'user-C',
            interactionType: 'VoiceCommand',
            content: 'Open email',
            device: 'Smartphone',
            location: 'Gym',
            outcome: 'Success'
          },
          {
            id: 8,
            virtualId: 'virtual-2',
            timestamp: '2023-04-01 12:15:00',
            userId: 'user-A',
            interactionType: 'Gesture',
            content: 'Zoomed in',
            device: 'Tablet',
            location: 'Library',
            outcome: 'Success'
          },
          {
            id: 9,
            virtualId: 'virtual-1',
            timestamp: '2023-04-01 12:30:00',
            userId: 'user-D',
            interactionType: 'Chat',
            content: 'Scheduled a meeting',
            device: 'Desktop',
            location: 'Conference Room',
            outcome: 'Success'
          },
          {
            id: 10,
            virtualId: 'virtual-3',
            timestamp: '2023-04-01 12:45:00',
            userId: 'user-B',
            interactionType: 'VoiceCommand',
            content: 'Show notifications',
            device: 'Laptop',
            location: 'Kitchen',
            outcome: 'Error'
          }
        ]
      }
      this.RecordList = res.data
      this.pageTion.currentPage = this.pageTion.page
      this.pageTion.pageSize = this.pageTion.limit
      this.pageTion.total = res.count
      // 测试环境  模拟数据结束  
      /***
       *  正式环境环境 调用接口
       */
       getRecords(recordContent)
          .then(res => {
            this.loading = false
            if (res.success == false) {
              this.$message({
                type: 'info',
                message: res.msg
              })
            } else {
              this.RecordList = res.data
              // 分页赋值
              this.pageTion.currentPage = this.pageTion.page
              this.pageTion.pageSize = this.pageTion.limit
              this.pageTion.total = res.count
            }
          })
          .catch(err => {
            this.loading = false
            this.$message.error('交互记录加载失败，请稍后再试！')
          })
    },
    // 分页插件事件
    callFather(parm) {
      this.pageTion.page = parm.currentPage
      this.pageTion.limit = parm.pageSize
      this.getdata(this.pageTion)
    },
    // 搜索事件
    search() {
      this.getdata(this.pageTion)
    },
    // 删除交互记录
    deleteRecord(index, row) {
      this.$confirm(`确定要删除交互记录吗?`, '删除', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          recordDelete(row.id)
            .then(res => {
              if (res.success===1) {
                this.$message({
                  type: 'success',
                  message: '交互记录已删除!'
                })
                this.getdata(this.pageTion)
              } else {
                this.$message({
                  type: 'info',
                  message: res.msg
                })
              }
            })
            .catch(err => {
              this.loading = false
              this.$message.error('交互记录删除失败！')
            })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除交互记录'
          })
        })
    },
    addRecordFromForm() {  
      this.$refs.form.validate((valid) => {  
        if (valid) {  
          // 表单验证通过，将表单数据添加到 interactionRecords 数组中  
          this.interactionRecords.push({  
            ...this.form  
          });  
          // 重置表单  
          this.$refs.form.resetFields();  
          // 关闭对话框  
          this.dialogVisible = false;  
        } else {  
          console.log('表单验证失败');  
          return false;  
        }  
      });  
    }  
  }
}
</script>
<!-- 学术库内容审核 -->
<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>学术库内容审核</el-breadcrumb-item>
    </el-breadcrumb>
    <div>
      <el-container>
        <el-main>
          <el-row>
            <el-col :span="8">
              <el-input placeholder="请输入内容关键字进行搜索" v-model="searchQuery"></el-input>
            </el-col>
            <el-col :span="4" style="margin-left: 20px;">
              <el-select v-model="selectedStatus" placeholder="请选择状态">
                <el-option v-for="item in statuses" :key="item.value" :label="item.label" :value="item.value"></el-option>
              </el-select>
            </el-col>
            <el-col :span="4">
              <el-button icon="el-icon-search" type="success"  @click="learnDate">搜索</el-button>
            </el-col>
          </el-row>
          <el-table  border :data="filteredData" style="width: 100%">
            <el-table-column  align='center' prop="id" label="ID" width="80"></el-table-column>
            <el-table-column align='center' prop="articleTitle" label="标题"></el-table-column>
            <el-table-column align='center'  prop="contentSummary" label="内容"></el-table-column>
            <el-table-column align='center' prop="status" label="状态" width="120" sortable></el-table-column>
            <el-table-column align='center' label="操作" width="180">
              <template slot-scope="scope">
                <el-button type="info"    @click="editItem(scope.row)">编辑</el-button>
                <el-button v-if="scope.row.status=='待审核'" type="primary"  @click="approveItem(scope.row)"> 审核</el-button>
                <el-button v-if="scope.row.status=='已拒绝'" type="primary"  @click="approveItem(scope.row)"> 重审</el-button>
                <el-button  v-if="scope.row.status=='已审核'" disabled  type="primary"   @click="approveItem(scope.row)"> 已审</el-button>
              </template>
            </el-table-column>
          </el-table>
          <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage"
            :page-sizes="[10, 20, 50, 100]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper"
            :total="totalData"></el-pagination>
        </el-main>
      </el-container>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      searchQuery: '',
      selectedStatus: '',
      statuses: [
        { value: 'pending', label: '待审核' },
        { value: 'approved', label: '已审核' },
        { value: 'rejected', label: '已拒绝' },
      ],
      currentPage: 1,
      pageSize: 10,
      totalData: 0,
      academicData: [], // 学术库内容数据  
      filteredData: [], // 筛选后的数据  
    }
  },
  // 监听 searchQuery 和 selectedStatus 的变化，当它们变化时重新获取数据  
  watch: {
    searchQuery: {
      handler() {
        this.learnDate();
      },
      deep: true,
    },
    selectedStatus(newVal) {
      if (newVal) {
        this.learnDate();
      }
    },
  },
  created() {
    this.getdata()
  },
  methods: {
    // 获取数据列表
    getdata() {
      // 模拟数据开始
      let res = {
        code: 0,
        msg: null,
        count: 43,
        data: [
          {
            "id": 1,
            "articleTitle": "数字虚拟人技术在远程教育中的应用",
            "author": "张三",
            "publicationDate": "2023-03-15",
            "contentSummary": "探讨了数字虚拟人在远程教育中的教学辅助作用，提出了新的教学模式。",
            "academicField": "教育技术",
            'status':'已审核'
          },
          {
            "id": 2,
            "articleTitle": "基于深度学习的虚拟人表情生成算法研究",
            "author": "李四",
            "publicationDate": "2023-02-20",
            "contentSummary": "设计并实现了一种基于深度学习框架的虚拟人表情生成方法，提高了表情的真实性。",
            "academicField": "计算机视觉",
            'status':'已审核'
          },
          {
            "id": 3,
            "articleTitle": "虚拟人行为模拟在人机交互中的应用分析",
            "author": "王五",
            "publicationDate": "2023-01-10",
            "contentSummary": "分析了虚拟人行为模拟在提升人机交互体验方面的作用，并提出了优化建议。",
            "academicField": "人机交互",
            'status':'已审核'
          },
          {
            "id": 4,
            "articleTitle": "数字虚拟人语音合成技术研究进展",
            "author": "赵六",
            "publicationDate": "2022-12-01",
            "contentSummary": "综述了近年来数字虚拟人语音合成技术的研究现状和发展趋势。",
            "academicField": "语音技术",
            'status':'已拒绝'
          },
          {
            "id": 5,
            "articleTitle": "基于AI的数字虚拟人情感识别系统",
            "author": "孙七",
            "publicationDate": "2022-11-15",
            "contentSummary": "构建了一个基于人工智能的数字虚拟人情感识别系统，实现了对用户情绪的准确识别。",
            "academicField": "人工智能",
            'status':'待审核'
          },
          {
            "id": 6,
            "articleTitle": "数字虚拟人在医疗领域的应用探索",
            "author": "周八",
            "publicationDate": "2022-10-20",
            "contentSummary": "探讨了数字虚拟人在医疗咨询、康复训练等方面的应用潜力和挑战。",
            "academicField": "医疗技术",
            'status':'待审核'
          },
          {
            "id": 7,
            "articleTitle": "数字虚拟人实时渲染技术研究",
            "author": "吴九",
            "publicationDate": "2022-09-10",
            "contentSummary": "研究了数字虚拟人实时渲染的关键技术，提高了虚拟人的渲染质量和效率。",
            "academicField": "计算机图形学",
            'status':'待审核'
          },
          {
            "id": 8,
            "articleTitle": "基于深度神经网络的虚拟人动作捕捉系统",
            "author": "郑十",
            "publicationDate": "2022-08-15",
            "contentSummary": "设计了一种基于深度神经网络的虚拟人动作捕捉系统，实现了对真实人体动作的准确捕捉和转换。",
            "academicField": "运动捕捉",
            'status':'待审核'
          },
          {
            "id": 9,
            "articleTitle": "数字虚拟人面部细节生成算法优化",
            "author": "陈十一",
            "publicationDate": "2022-07-01",
            "contentSummary": "针对数字虚拟人面部细节生成算法进行了优化，提升了虚拟人面部表情的自然度和逼真度。",
            "academicField": "计算机图形学",
            'status':'待审核'
          },
          {
            "id": 10,
            "articleTitle": "数字虚拟人智能问答系统的设计与实现",
            "author": "刘十二",
            "publicationDate": "2022-06-15",
            "contentSummary": "构建了一个具有智能问答功能的数字虚拟人系统，实现了与用户的自然语言交互。",
            "academicField": "自然语言处理",
            'status':'待审核'
          }
        ]
      }
      this.filteredData = res.data
      this.totalData = this.filteredData.length;
      // 正式环境环境 调用接口
       this.learnDate()
    },
    learnDate() {
      // 仅模拟数据  
      this.filteredData = this.academicData.filter(item => {
        return (
          item.title.includes(this.searchQuery) &&
          item.status === this.selectedStatus
        );
      });
      this.totalData = this.filteredData.length;
      // 根据当前页码和每页数量来截取数据  
      this.filteredData = this.filteredData.slice(
        (this.currentPage - 1) * this.pageSize,
        this.currentPage * this.pageSize
      );
    },
    handleSizeChange(val) {
      this.pageSize = val;
      this.learnDate();
    },
    handleCurrentChange(val) {
      this.currentPage = val;
      this.learnDate();
    },
    // 编辑
    editItem(item) {
    if (!item || !item.id) {  
        throw new Error('Invalid item. Item ID is required.');  
    }  
    if (!currentUser.isAdmin) {  
        throw new Error('You do not have permission to edit items.');  
    }  
    const allowedFieldsToUpdate = ['name', 'description', 'category']; // 允许编辑的字段  
    const fieldsToUpdate = Object.keys(item).filter(field => allowedFieldsToUpdate.includes(field));  
    if (fieldsToUpdate.length === 0) {  
        throw new Error('No valid fields to update.');  
    } 
    const updatedItem = updateItemInDatabase(item.id, { ...item, fieldsToUpdate });  
    return updatedItem;  
    },
    // 审核
    approveItem(item) {
      if (!item || !item.id) {  
        throw new Error('Invalid item');  
    }  
    if (!currentUser.isAdmin) {  
        throw new Error('You do not have permission to approve items');  
    }  
    updateItemStatus(item.id, 'approved'); 
    console.log(`Item ${item.id} has been approved.`);  
    return {  
        status: 'approved',  
        itemId: item.id  
    };  
    },
  }
}
</script>
<!-- 学术库问答训练 -->
<template>
  <div>
    <div>
      <el-container>
        <el-aside width="200px">
        </el-aside>
        <el-main>
          <el-card class="box-card">
            <div slot="header" class="clearfix">
              <span>学术库问答训练</span>
              <el-button style="margin-left: 30px;" type="primary" @click="addNewQuestion">添加新问答</el-button>
            </div>
            <el-table :data="questions" style="width: 100%" >
              <el-table-column prop="question" label="问题" width="200"></el-table-column>
              <el-table-column prop="answer" label="答案" width="500"></el-table-column>
              <el-table-column prop="category" label="类别" width="120"></el-table-column>
              <el-table-column prop="difficulty" label="难度" width="100"></el-table-column>
              <el-table-column prop="relatedTechnology" label="关联技术" width="150"></el-table-column>
              <el-table-column prop="remark" label="备注" width="130"></el-table-column>
              <el-table-column label="操作" width="180">
                <template slot-scope="scope">
                  <el-button type="text" @click="editQuestion(scope.row)">编辑</el-button>
                  <el-button type="text" @click="deleteQuestion(scope.row.id)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-card>
        </el-main>
      </el-container>
      <!-- 问答详情和编辑模态框 -->
      <el-dialog :visible.sync="dialogVisible" :title="dialogTitle">
        <el-form :model="currentQuestion" ref="questionForm" label-width="120px">
          <el-form-item label="问题内容">
            <el-input v-model="currentQuestion.question"></el-input>
          </el-form-item>
          <el-form-item label="类别">
            <el-input v-model="currentQuestion.category"></el-input>
          </el-form-item>
          <el-form-item label="难度">
            <el-input v-model="currentQuestion.difficulty"></el-input>
          </el-form-item>
          <el-form-item label="关联技术">
            <el-input v-model="currentQuestion.difficulty"></el-input>
          </el-form-item>
          <el-form-item label="答案内容">
            <el-input v-model="currentQuestion.answer.answer"></el-input>
          </el-form-item>
          <el-form-item label="备注">
            <el-input v-model="currentQuestion.answer.remark"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="submitQuestion">提交</el-button>
            <el-button @click="dialogVisible = false">取消</el-button>
          </el-form-item>
        </el-form>
      </el-dialog>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      questions: [], // 问答列表  
      currentQuestion: { // 当前编辑的问答 
        id: null,
        question: '',
        answer: '',
        category: '',
        difficulty: '',
        relatedTechnology: '',
        remark: '',
      },
      dialogVisible: false, // 模态框显示状态  
      dialogTitle: '添加新问答', // 模态框标题  
    };
  },
  created() {
    this.getquestions() 
  },
  methods: {
    getquestions() {
      let res = {
        data: [
          {
            id:1,
            question: '什么是数字虚拟人?',
            answer: '数字虚拟人是一种基于计算机图形学、人工智能等技术创建的虚拟角色，能够模拟人类的行为和交互。',
            category: '定义',
            difficulty: '简单',
            relatedTechnology: '计算机图形学、人工智能',
            remark: ''
          },
          {
            id:2,
            question: '数字虚拟人有哪些应用场景?',
            answer: '数字虚拟人可应用于游戏、影视、直播、虚拟客服、教育培训等领域，提供丰富的交互体验。',
            category: '应用场景',
            difficulty: '简单',
            relatedTechnology: '游戏开发、影视制作',
            remark: ''
          },
          {
            id:3,
            question: '如何创建数字虚拟人?',
            answer: '创建数字虚拟人涉及3D建模、动画设计、语音合成等多个环节，需要专业的技术和工具支持。',
            category: '创建流程',
            difficulty: '中等',
            relatedTechnology: '3D建模、动画设计',
            remark: ''
          },
          {
            id:4,
            question: '数字虚拟人的表情如何制作?',
            answer: '数字虚拟人的表情制作通常通过面部捕捉技术实现，将真实人的表情映射到虚拟人模型上，使其表情更加自然生动。',
            category: '表情制作',
            difficulty: '中等',
            relatedTechnology: '面部捕捉技术',
            remark: ''
          },
          {
            id:5,
            question: '数字虚拟人的语音是如何合成的?',
            answer: '数字虚拟人的语音合成利用文本转语音技术，将文本信息转化为自然的语音输出，使其能够与人类进行语音交互。',
            category: '语音合成',
            difficulty: '中等',
            relatedTechnology: '文本转语音技术',
            remark: ''
          },
          {
            id:6,
            question: '数字虚拟人能否进行实时交互?',
            answer: '是的，数字虚拟人可以通过自然语言处理、语音识别等技术实现实时交互，能够与用户进行对话和互动。',
            category: '实时交互',
            difficulty: '困难',
            relatedTechnology: '自然语言处理、语音识别',
            remark: ''
          },
          {
            id:7,
            question: '数字虚拟人的发展前景如何?',
            answer: '随着技术的不断进步和应用场景的扩大，数字虚拟人的发展前景非常广阔，将在更多领域发挥重要作用。',
            category: '发展前景',
            difficulty: '困难',
            relatedTechnology: '虚拟现实、增强现实',
            remark: ''
          },
          {
            id:8,
            question: '如何评价数字虚拟人的逼真程度?',
            answer: '评价数字虚拟人的逼真程度可以从外观、动作、语音等多个方面进行综合评估，需要考虑模型的精细度、动作的流畅性以及语音的自然度等因素。',
            category: '逼真程度评价',
            difficulty: '困难',
            relatedTechnology: '视觉识别、语音评估',
            remark: ''
          },
          {
            id:9,
            question: '数字虚拟人能否替代真实演员?',
            answer: '数字虚拟人可以在一定程度上模拟真实演员的表演，但目前还无法完全替代真实演员，因为真实演员的表演具有独特的情感和个性魅力。',
            category: '替代真实演员',
            difficulty: '困难',
            relatedTechnology: '表演艺术、情感表达',
            remark: ''
          },
          {
            id:10,
            question: '数字虚拟人在哪些领域具有创新应用?',
            answer: '数字虚拟人在游戏、影视、虚拟偶像、在线教育等领域具有创新应用，能够为用户提供沉浸式的体验和全新的交互方式。',
            category: '创新应用',
            difficulty: '困难',
            relatedTechnology: '虚拟现实技术、人工智能算法',
            remark: ''
          }
        ]
      }
      this.questions = res.data
      // //正式环境 调用接口
      const apiUrl = '/api/get/questions';
      this.axios.post(apiUrl, id)
            .then(response => {
              // 添加成功，更新问答列表
              this.fetchQuestions();
              this.message({ message: '获取数据成功', type: 'success' });
            }).catch(error => {
              console.error('获取数据失败', error); this.message.error('获取数据失败!');
            });  
    },
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.$message({
            type: 'success',
            message: '提交成功!'
          })
          //进行表单数据的提交处理，
          this.submitToServer(this.form);
        } else {
          this.$message({
            type: 'info',
            message: res.msg
          })
          return false;
        }
      });
    },
    fetchQuestions() {  
    },
    addNewQuestion() {
      this.dialogTitle = '添加新问答';
      this.currentQuestion = {
      };
      this.dialogVisible = true;
    },
    editQuestion(question) {
      this.dialogTitle = '编辑问答';
      this.currentQuestion = { ...question };
      this.dialogVisible = true;
    },
    //删除问答
    deleteQuestion(id) {
      this.$confirm(`确定要删除吗?`, '删除', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          const apiUrl = '/api/delete/questions';
          this.axios.post(apiUrl, id)
            .then(response => {
              // 添加成功，更新问答列表
              this.fetchQuestions();
              this.message({ message: '删除成功', type: 'success' });
            }).catch(error => {
              console.error('删除问答失败', error); this.message.error('删除失败');
            });
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
        })
    },
    submitQuestion() {
      this.refs.questionForm.validate((valid) => {
        if (valid) {
          // 调用API保存或更新问答 
          if (this.currentQuestion.id) {
            // 更新问答 
            this.updateQuestion();
          } else {
            // 添加新问答 
            this.addQuestion();
          } this.dialogVisible = false;
        } else {
          console.log('表单验证失败'); return false;
        }
      });
    },
    addQuestion() {
      const apiUrl = '/api/questions';
      this.axios.post(apiUrl, this.currentQuestion)
        .then(response => {
          // 添加成功，更新问答列表
          this.fetchQuestions();
          this.message({ message: '添加成功', type: 'success' });
        }).catch(error => {
          console.error('添加问答失败', error); this.message.error('添加失败');
        });
    },
    updateQuestion() {
      const apiUrl = `/api/questions/${this.currentQuestion.id}`;
      this.axios.put(apiUrl, this.currentQuestion)
        .then(response => {
          // 更新成功，更新问答列表 
          this.fetchQuestions(); this.message({
            message: '更新成功',
            type: 'success'
          });
        })
        .catch(error => {
          console.error('更新问答失败', error);
          this.$message.error('更新失败');
        });
    }
  }
}
</script>
